package com.iweb.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iweb.dto.AdminIdTto;
import com.iweb.dto.AdminListInfo;
import com.iweb.exception.AccountException;
import com.iweb.exception.PassWordException;
import com.iweb.model.Admin;
import com.iweb.page.DataGrid;
import com.iweb.resp.R;
import com.iweb.service.AdminService;
import com.iweb.utils.JwtUtil;
import com.iweb.vo.AdminLoginVO;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import sun.plugin2.os.windows.SECURITY_ATTRIBUTES;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

;import java.util.HashMap;
import java.util.Map;

@CrossOrigin(allowCredentials = "true")
@RestController
@RequiredArgsConstructor
public class AdminController {

    final private AdminService adminService;

    final static String USER_KEY = "admin_key";

    // @PostMapping("queryId/{id}")
    // public R<AdminIdTto> queryId(@PathVariable long id) throws Exception {

    // Admin admin = adminService.findId(id);
    // AdminIdTto data = new AdminIdTto();
    // BeanUtils.copyProperties(admin, data);

    // return R.success("query admin", data);
    // }

    @PostMapping("/admin/login")
    public R<AdminIdTto> login(@RequestBody AdminLoginVO adminLoginVO, @ApiIgnore HttpSession session, @ApiIgnore HttpServletResponse response) throws Exception {

        String phone = adminLoginVO.getPhone();
        Admin admin = adminService.findPhone(phone);
        if (ObjectUtil.isNull(admin)) {
            throw new AccountException("电话号码不存在");
        }
        String pwd = SecureUtil.sha256(adminLoginVO.getPassword());
        if (!StrUtil.equals(admin.getPassword(), pwd)) {
            throw new PassWordException("密码错误");
        }

        AdminIdTto data = new AdminIdTto();
        BeanUtils.copyProperties(admin, data);


        // data 转 json
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonData = objectMapper.writeValueAsString(data);
//        session.setAttribute(USER_KEY, data);

        // 放 token 中 生成一个 token
        Map<String, Object> claims = new HashMap<>();
        claims.put(USER_KEY, jsonData);
        String uuid = UUID.randomUUID().toString();
        String token = JwtUtil.generateToken(uuid, claims);
        // token 响应给 客户端
        // 允许客户端接受自定义参数
        response.addHeader("Access-Control-Expose-Headers", "token");
        response.addHeader("token", token);

        return R.success("login ok", data);

    }


    @Cacheable(cacheNames = "admin", key = "#root.methodName+\"::\"+#current", condition = "#current==1")
    @PostMapping("/admin/list/{current}/{size}")
    public R<DataGrid<AdminListInfo>> list(@PathVariable int current, @PathVariable int size) throws Exception {
        DataGrid<AdminListInfo> dataGrid = adminService.findList(current, size);
        return R.success("list", dataGrid);
    }

    @PostMapping("/admin/pwd")
    public R<?> changePwd(@RequestBody Admin admin, @ApiIgnore HttpServletRequest request) throws Exception {
        // 修改密码需要 adminId(从 token 中获取) 和 password(客户端发送)

        // 注意 ： 进入这个方法的请求 一定要 携带 token 的, 应该写一个 拦截器 来拦截器所有需要 token 的请求, 如果没有token 直接返回

        String token = request.getHeader("token");
        Claims claims = JwtUtil.extractClaims(token);
        String tokenValue = claims.get(USER_KEY).toString();
        ObjectMapper objectMapper = new ObjectMapper();
        AdminIdTto adminIdTto = objectMapper.readValue(tokenValue, AdminIdTto.class);
        Long adminId = adminIdTto.getAdminId();

        admin.setAdminId(adminId);
        // 调用修改  service - mapper 调用 省略

        return R.success("change pwd");
    }

}
